package com.digicom.service.comment.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.digicom.common.constant.Constants;
import com.digicom.common.core.utils.SecurityUtils;
import com.digicom.common.entity.Article;
import com.digicom.common.entity.Comment;
import com.digicom.common.exception.ServiceException;
import com.digicom.common.mapper.ArticleMapper;
import com.digicom.common.mapper.CommentMapper;
import com.digicom.service.comment.CommentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 评论服务实现类
 */
@Slf4j
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private KafkaTemplate<String, Object> kafkaTemplate;

    @Override
    public Page<Comment> listArticleComments(Long articleId, Page<Comment> page) {
        if (articleId == null) {
            throw new ServiceException("文章ID不能为空");
        }
        return commentMapper.selectArticleComments(page, articleId);
    }

    @Override
    public Page<Comment> listPendingComments(Page<Comment> page) {
        return commentMapper.selectPendingComments(page);
    }

    @Override
    public Page<Comment> listUserComments(Long userId, Page<Comment> page) {
        if (userId == null) {
            throw new ServiceException("用户ID不能为空");
        }
        return commentMapper.selectUserComments(page, userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addComment(Comment comment) {
        if (comment == null || comment.getArticleId() == null || StringUtils.isBlank(comment.getContent())) {
            throw new ServiceException("评论信息不完整");
        }

        // 查询文章是否存在
        Article article = articleMapper.selectById(comment.getArticleId());
        if (article == null) {
            throw new ServiceException("文章不存在");
        }

        // 设置文章标题
        comment.setArticleTitle(article.getTitle());

        // 设置评论状态，根据系统配置决定是否需要审核
        String needReview = redisTemplate.opsForValue().get("sys.comment.need_review").toString();
        if ("true".equals(needReview)) {
            comment.setStatus(Constants.COMMENT_STATUS_PENDING);
        } else {
            comment.setStatus(Constants.COMMENT_STATUS_NORMAL);
        }

        // 设置同步状态
        comment.setSyncApp("0");

        // 设置初始点赞数和回复数
        comment.setLikeCount(0);
        comment.setReplyCount(0);
        comment.setCreateTime(new Date());

        // 保存评论
        boolean result = save(comment);
        if (!result) {
            throw new ServiceException("添加评论失败");
        }

        // 如果是回复评论，更新父评论的回复数
        if (comment.getParentId() != null && comment.getParentId() > 0) {
            Comment parentComment = getById(comment.getParentId());
            if (parentComment != null) {
                parentComment.setReplyCount(parentComment.getReplyCount() + 1);
                updateById(parentComment);
            }
        }

        // 更新文章评论数
        if (Constants.COMMENT_STATUS_NORMAL.equals(comment.getStatus())) {
            updateArticleCommentCount(comment.getArticleId());
        }

        // 如果评论状态为已发布，则同步到APP
        if (Constants.COMMENT_STATUS_NORMAL.equals(comment.getStatus())) {
            syncCommentToApp(comment.getCommentId());
        }

        return comment.getCommentId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reviewComment(Long commentId, String status, String reviewBy, String reviewRemark) {
        if (commentId == null || StringUtils.isBlank(status)) {
            throw new ServiceException("参数不能为空");
        }

        Comment comment = getById(commentId);
        if (comment == null) {
            throw new ServiceException("评论不存在");
        }

        // 更新评论状态
        comment.setStatus(status);
        comment.setReviewBy(reviewBy);
        comment.setReviewTime(new Date());
        comment.setReviewRemark(reviewRemark);
        comment.setUpdateTime(new Date());
        boolean result = updateById(comment);
        
        if (result) {
            // 如果审核通过，更新文章评论数
            if (Constants.COMMENT_STATUS_NORMAL.equals(status)) {
                updateArticleCommentCount(comment.getArticleId());
                // 审核通过后，同步到APP
                syncCommentToApp(commentId);
            }
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteComments(Long[] commentIds) {
        if (commentIds == null || commentIds.length == 0) {
            throw new ServiceException("评论ID不能为空");
        }

        // 查询评论信息，用于更新文章评论数
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Comment::getCommentId, Arrays.asList(commentIds))
                   .eq(Comment::getStatus, Constants.COMMENT_STATUS_NORMAL);
        
        List<Comment> comments = list(queryWrapper);
        
        // 逻辑删除评论
        boolean result = removeByIds(Arrays.asList(commentIds));

        // 更新相关文章的评论数
        if (result) {
            for (Comment comment : comments) {
                updateArticleCommentCount(comment.getArticleId());
            }
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean syncCommentToApp(Long commentId) {
        if (commentId == null) {
            throw new ServiceException("评论ID不能为空");
        }

        Comment comment = getById(commentId);
        if (comment == null) {
            throw new ServiceException("评论不存在");
        }

        try {
            // 发送消息到Kafka，通知APP同步评论数据
            kafkaTemplate.send(Constants.TOPIC_COMMENT_SYNC, comment);
            
            // 更新同步状态
            comment.setSyncApp("1");
            comment.setUpdateTime(new Date());
            return updateById(comment);
        } catch (Exception e) {
            log.error("同步评论到APP失败", e);
            throw new ServiceException("同步评论到APP失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteComment(Long commentId, Long userId) {
        if (commentId == null) {
            throw new ServiceException("评论ID不能为空");
        }

        Comment comment = getById(commentId);
        if (comment == null) {
            throw new ServiceException("评论不存在");
        }

        // 验证权限（评论作者或管理员可删除）
        if (!userId.equals(comment.getUserId()) && !SecurityUtils.isAdmin()) {
            throw new ServiceException("无权删除该评论");
        }

        // 逻辑删除评论
        boolean result = removeById(commentId);

        // 如果是已发布状态的评论，需要更新文章评论数
        if (result && Constants.COMMENT_STATUS_NORMAL.equals(comment.getStatus())) {
            updateArticleCommentCount(comment.getArticleId());
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long replyComment(Comment comment) {
        if (comment == null || comment.getParentId() == null || StringUtils.isBlank(comment.getContent())) {
            throw new ServiceException("回复评论信息不完整");
        }

        // 查询父评论是否存在
        Comment parentComment = getById(comment.getParentId());
        if (parentComment == null) {
            throw new ServiceException("父评论不存在");
        }

        // 设置文章ID和标题
        comment.setArticleId(parentComment.getArticleId());
        comment.setArticleTitle(parentComment.getArticleTitle());

        // 设置评论状态，根据系统配置决定是否需要审核
        String needReview = redisTemplate.opsForValue().get("sys.comment.need_review").toString();
        if ("true".equals(needReview)) {
            comment.setStatus(Constants.COMMENT_STATUS_PENDING);
        } else {
            comment.setStatus(Constants.COMMENT_STATUS_NORMAL);
        }

        // 设置同步状态
        comment.setSyncApp("0");

        // 设置初始点赞数和回复数
        comment.setLikeCount(0);
        comment.setReplyCount(0);
        comment.setCreateTime(new Date());

        // 保存回复评论
        boolean result = save(comment);
        if (!result) {
            throw new ServiceException("回复评论失败");
        }

        // 更新父评论的回复数
        parentComment.setReplyCount(parentComment.getReplyCount() + 1);
        updateById(parentComment);

        // 更新文章评论数
        if (Constants.COMMENT_STATUS_NORMAL.equals(comment.getStatus())) {
            updateArticleCommentCount(comment.getArticleId());
        }

        // 如果评论状态为已发布，则同步到APP
        if (Constants.COMMENT_STATUS_NORMAL.equals(comment.getStatus())) {
            syncCommentToApp(comment.getCommentId());
        }

        return comment.getCommentId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean autoReviewComment(Long commentId) {
        if (commentId == null) {
            throw new ServiceException("评论ID不能为空");
        }

        Comment comment = getById(commentId);
        if (comment == null) {
            throw new ServiceException("评论不存在");
        }

        // 检查评论内容是否包含敏感词
        boolean containsSensitiveWords = checkSensitiveWords(comment.getContent());
        
        // 根据敏感词检查结果决定评论状态
        String status = containsSensitiveWords ? Constants.COMMENT_STATUS_REJECTED : Constants.COMMENT_STATUS_NORMAL;
        String reviewRemark = containsSensitiveWords ? "包含敏感词汇，自动拒绝" : "系统自动审核通过";
        
        return reviewComment(commentId, status, "system", reviewRemark);
    }

    /**
     * 检查是否包含敏感词
     *
     * @param content 内容
     * @return 是否包含敏感词
     */
    private boolean checkSensitiveWords(String content) {
        if (StringUtils.isBlank(content)) {
            return false;
        }
        
        // 从Redis获取敏感词列表
        @SuppressWarnings("unchecked")
        java.util.List<String> sensitiveWords = (java.util.List<String>) redisTemplate.opsForValue().get("sys.comment.sensitive_words");
        if (sensitiveWords == null || sensitiveWords.isEmpty()) {
            return false;
        }
        
        // 检查内容是否包含敏感词
        for (String word : sensitiveWords) {
            if (content.contains(word)) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * 更新文章评论数
     *
     * @param articleId 文章ID
     */
    private void updateArticleCommentCount(Long articleId) {
        if (articleId == null) {
            return;
        }

        // 统计文章评论数
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getArticleId, articleId)
               .eq(Comment::getStatus, Constants.COMMENT_STATUS_NORMAL)
               .eq(Comment::getDelFlag, "0");
        long count = count(wrapper);

        // 更新文章评论数
        Article article = articleMapper.selectById(articleId);
        if (article != null) {
            article.setCommentCount(count);
            articleMapper.updateById(article);
        }
    }

    /**
     * 统计文章评论数量
     */
    @Override
    public int countArticleComments(Long articleId) {
        if (articleId == null) {
            return 0;
        }
        
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getArticleId, articleId)
               .eq(Comment::getStatus, Constants.COMMENT_STATUS_NORMAL);
        
        return Math.toIntExact(count(wrapper));
    }

    /**
     * 对评论进行审核
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean auditComment(Long commentId, String status, String reviewBy, String reviewRemark) {
        return reviewComment(commentId, status, reviewBy, reviewRemark);
    }

    /**
     * 获取某个评论的所有回复
     */
    @Override
    public List<Comment> listReplies(Long commentId) {
        if (commentId == null) {
            return new ArrayList<>();
        }
        
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getParentId, commentId)
               .eq(Comment::getStatus, Constants.COMMENT_STATUS_NORMAL)
               .orderByAsc(Comment::getCreateTime);
               
        return list(wrapper);
    }

    /**
     * 查询文章评论列表
     */
    @Override
    public Page<Comment> listCommentsByArticle(Long articleId, Page<Comment> page) {
        return listArticleComments(articleId, page);
    }

    /**
     * 查询用户评论列表
     */
    @Override
    public Page<Comment> listCommentsByUser(Long userId, Page<Comment> page) {
        return listUserComments(userId, page);
    }
}
